defmodule SockWorkstation.CtrlMgrGen do
  use GenServer

  @name __MODULE__
  # require Logger

  alias SockWorkstation.{CoopMgrGen, SessionMgr}

  # defmodule CtrlMgrSt do
  #   defstruct self_pid: nil,
  #             ctrl_mgr_pid: self_pid,
  #             ctrl_cli_pid: nil
  # end

  # Client API

  def start_link(_initial_value) do
    GenServer.start_link(@name, [], name: @name)
  end

  def get_state() do
    GenServer.call(@name, :get_state)
  end

  # Server Callbacks

  @impl true
  def init(_initial_value) do
    self_pid = self()
    # Process.send_after(self_pid, :run_ctrl_client, 200)
    state =
      %{
        ctrl_mgr_pid: self_pid,
        ctrl_cli_pid: nil
      }

    IO.puts("CtrlMgrGen started")
    {:ok, state}
  end

  def fetch_ctl_pid(pid) do
    GenServer.cast(@name, {:fetch_ctl_pid, pid})
  end

  def start_peer_coop(session_id, uid) do
    SessionMgr.stop_session(session_id)
    Process.sleep(120)
    SessionMgr.start_session(session_id)
    CoopMgrGen.runfirst_for_uid(session_id, uid)
  end


  def fetch_uid(user_id, session_id) do
    GenServer.cast(@name, {:fetch_uid, user_id, session_id})
  end

  def rm_uid(user_id) do
    GenServer.cast(@name, {:rm_uid, user_id})
  end

  @impl true
  def handle_call(:get_state, _from, state) do
    {:reply, state, state}
  end

  @impl true
  def handle_cast({:fetch_ctl_pid, pid}, state) do
    # state = %{state | ctrl_mgr_pid: pid}
    {:noreply, %{state | ctrl_cli_pid: pid}}
  end

  def handle_cast({:fetch_uid, user_id, session_id}, state) do
    {:noreply, Map.put(state, user_id, session_id)}
  end

  def handle_cast({:rm_uid, user_id}, state) do
    {:noreply, Map.delete(state, user_id)}
  end

  # def handle_cast({:add_coop_mgr_pid, pid}, state) do
  #   {:noreply, %{state | coop_mgr_pid: pid}}
  # end

  def rot5(string) do
    # 使用正则表达式替换字符串中的每个数字
    Regex.replace(~r/[0-9]/, string, fn char ->
      # 将匹配的数字字符转换为对应的 ROT5 字符
      rot5_char(char)
    end)
  end

  defp rot5_char(<<char>>) when char in ?0..?9 do
    # 计算 ROT5 转换后的字符
    <<rem(char - ?0 + 5, 10) + ?0>>
  end

  def rot13(string) do
    # 使用正则表达式替换字符串中的每个字母
    Regex.replace(~r/[a-zA-Z]/, string, fn char ->
      # 将匹配的字符转换为对应的 ROT13 字符
      rot13_char(char)
    end)
  end

  defp rot13_char(char) do
    case char do
      # 处理小写字母 a-z
      <<c>> when c in ?a..?z ->
        <<rem(c - ?a + 13, 26) + ?a>>

      # 处理大写字母 A-Z
      <<c>> when c in ?A..?Z ->
        <<rem(c - ?A + 13, 26) + ?A>>

      # 其他字符保持不变
      _ ->
        char
    end
  end
end

# def handle_call({:add_decoder, {pid, port}}, _from, state) do
#   state = %CtlMgrSession{state | decoder: %{to_pcm_pid: pid, decoder_port: port}}
#   {:reply, :ok, state}
# end

# def handle_call({:add_encoder, {pid, port}}, _from, state) do
#   state = %CtlMgrSession{state | encoder: %{to_opus_pid: pid, encoder_port: port}}
#   {:reply, :ok, state}
# end

# def handle_cast(:rm_ctrl_pid, state) do
#   {:noreply, %{state | ctrl_cli_pid: nil}}
# end

# def handle_call(:rm_coop_mgr_pid, _from, state) do
#   {:reply, :ok, %{state | coop_mgr_pid: nil}}
# end

# defmodule CtlMgrSession do
# defstruct ctrl_mgr_pid: nil, coop_mgr_pid: nil

#   # to_opus_pid: "",
#   # to_pcm_pid: "",
#   # session_id: "",
#   # coop_pid: "",
#   # ffmpeg_pid: ""
# end

# def add_coop_mgr_pid(pid) do
#   GenServer.cast(@name, {:add_coop_mgr_pid, pid})
# end

# def rm_coop_mgr_pid() do
#   GenServer.call(@name, :rm_coop_mgr_pid)
# end

# def rm_ctrl_pid() do
#   GenServer.cast(@name, :rm_ctrl_pid)
# end

# def uid_peer_session(user_id, session_id) do
#   GenServer.cast(@name, {:uid_peer_session, user_id, session_id})
# end

# def add_coop_pid(pid) do
#   GenServer.call(@name, {:add_coop_pid, pid})
# end

# def uid_peer_session(session_id) do
#   GenServer.call(@name, {:uid_peer_session, session_id})
# end

# def add_encoder_pid(pid) do
#   GenServer.call(@name, {:add_encoder_pid, pid})
# end

# def add_decoder_pid(pid) do
#   GenServer.call(@name, {:add_decoder_pid, pid})
# end

# def add_ffmpeg_pid(pid) do
#   GenServer.call(@name, {:add_ffmpeg_pid, pid})
# end

# def handle_cast({:uid_peer_session, user_id, session_id}, state) do
#   # SockWorkstation.CoopHelperSup.start_coop_mgr(session_id)
#   # case SockWorkstation.CoopHelperSup.start_coop_mgr(session_id) do
#   #   {:ok, _pid} ->
#   #     IO.puts("start coop mgr success")

#   #   {:error, {:already_started, pid}} ->
#   #     SockWorkstation.CtrlMgrGen.add_coop_mgr_pid(pid)

#   #   {:error, _} ->
#   #     IO.puts("start coop mgr failed")
#   # end

#   {:noreply, Map.merge(state, %{user_id => session_id})}
# end

# with {:ok, _pid} <- CoopHelperSup.super_coop_mgr(session_id),
#      {:ok, _pid} <- CoopHelperSup.super_pcm_encode(session_id),
#      {:ok, _pid} <- CoopHelperSup.super_nif_codec(session_id),
#      {:ok, _pid} <- CoopHelperSup.super_asr_helper(session_id),
#      {:ok, _pid} <- CoopHelperSup.super_tts_helper(session_id),
#     #  {:ok, _pid} <- CoopHelperSup.super_vad_client(session_id),
#      {:ok, _pid} <- CoopHelperSup.super_frame_queue(session_id),
#      {:ok, _pid} <- CoopHelperSup.super_coop_client(session_id) do
#   CoopMgrGen.runfirst_for_uid(session_id, uid)
# end

# CoopHelperSup.super_coop_mgr(session_id)
# CoopHelperSup.super_pcm_encode(session_id)
# CoopHelperSup.super_nif_codec(session_id)
# CoopHelperSup.super_asr_helper(session_id)
# CoopHelperSup.super_tts_helper(session_id)
# # CoopHelperSup.super_vad_client(session_id)
# CoopHelperSup.super_frame_queue(session_id)
# CoopHelperSup.super_coop_client(session_id)

# @impl true
# def handle_info(:run_ctrl_client, state) do
#   SockCtrlClient.start_link()
#   # Logger.info("Running Ctrl Client")
#   {:noreply, state}
# end
# def handle_call({:add_coop_pid, pid}, _from, state) do
#   state = %CtlMgrSession{state | coop_pid: pid}
#   {:reply, :ok, state}
# end

# def handle_call({:uid_peer_session, session_id}, _from, state) do
#   state = %CtlMgrSession{state | session_id: session_id}
#   {:reply, :ok, state}
# end

# def handle_call({:add_encoder_pid, pid}, _from, state) do
#   state = %CtlMgrSession{state | to_opus_pid: pid}
#   {:reply, :ok, state}
# end

# def handle_call({:add_decoder_pid, pid}, _from, state) do
#   state = %CtlMgrSession{state | to_pcm_pid: pid}
#   {:reply, :ok, state}
# end

# def handle_call({:add_ffmpeg_pid, pid}, _from, state) do
#   state = %CtlMgrSession{state | ffmpeg_pid: pid}
#   {:reply, :ok, state}
# end

# @impl true
# def handle_cast(:increment, state) do
#   {:noreply, state + 1}
# end
